/**
 * 
 */
package com.gr.experimental.model.impl;

import java.util.Collections;
import java.util.List;
import java.util.Map;

import com.gr.experimental.model.BuiltInElements;
import com.gr.experimental.model.Distribution;
import com.gr.experimental.model.MFrag;
import com.gr.experimental.model.MTheory;
import com.gr.experimental.model.MTheoryManager;
import com.gr.experimental.model.Node;
import com.gr.experimental.model.OVariable;
import com.gr.experimental.model.RVArgument;
import com.gr.experimental.model.RVClass;
import com.gr.experimental.model.RVClassInfluence;
import com.gr.experimental.model.ResidentNode;
import com.gr.experimental.model.UID;

/**
 * @author Karol Banczyk
 *
 */
public class MTheoryManagerImpl implements MTheoryManager {

	/**
	 * {@inheritDoc}
	 * @see com.gr.experimental.model.MTheoryManager#createMTheory(java.util.List)
	 */
	@Override
	public MTheory createMTheory(List<MFrag> mfrags, List<UID> uids, Map<String, UID> aliases) {
		
		if (mfrags == null) {
			mfrags = Collections.emptyList();
		}
		if (uids == null) {
			uids = Collections.emptyList();
		}
		if (aliases == null) {
			aliases = Collections.emptyMap();
		}
		
		return new MTheoryImpl(mfrags, uids, aliases);
	}

	/**
	 * {@inheritDoc}
	 * @see com.gr.experimental.model.MTheoryManager#createMFrag(java.util.List, java.util.List, java.util.List)
	 */
	@Override
	public MFrag createMFrag(String name, List<Node> contextNodes, List<Node> inputNodes,
			List<ResidentNode> residentNodes) {

		if (contextNodes == null) {
			contextNodes = Collections.emptyList();
		}
		if (inputNodes == null) {
			inputNodes = Collections.emptyList();
		}
		return new MFragImpl(name, contextNodes, inputNodes, residentNodes);
	}

	/**
	 * {@inheritDoc}
	 * @see com.gr.experimental.model.MTheoryManager#createUID(java.lang.String)
	 */
	@Override
	public UID createUID(String name) {
		return new UIDImpl(name);
	}

	/**
	 * {@inheritDoc}
	 * @see com.gr.experimental.model.MTheoryManager#createNode(com.gr.experimental.model.RVClass, java.util.List)
	 */
	@Override
	public Node createNode(RVClass rvClass, List<? extends RVArgument> arguments) {
		if (arguments == null) {
			arguments = Collections.emptyList();
		}
		return new NodeImpl(rvClass, arguments);
	}

	/**
	 * {@inheritDoc}
	 * @see com.gr.experimental.model.MTheoryManager#createResidentNode(com.gr.experimental.model.RVClass, com.gr.experimental.model.Distribution, java.util.List, java.util.List)
	 */
	@Override
	public ResidentNode createResidentNode(RVClass rvClass,
			Distribution distribution, List<? extends RVArgument> arguments,
			List<? extends Node> parents) {
		if (arguments == null) arguments = Collections.emptyList();
		return new ResidentNodeImpl(rvClass, distribution, arguments, parents);
	}

	/**
	 * {@inheritDoc}
	 * @see com.gr.experimental.model.MTheoryManager#createResidentNode(com.gr.experimental.model.RVClass, com.gr.experimental.model.Distribution, java.util.List, java.util.List)
	 */
	@Override
	public ResidentNode createResidentNode(RVClass rvClass,
			Distribution distribution, List<? extends RVArgument> arguments) {
		if (arguments == null) arguments = Collections.emptyList();
		return new ResidentNodeImpl(rvClass, distribution, arguments);
	}

	/**
	 * {@inheritDoc}
	 * @see com.gr.experimental.model.MTheoryManager#createRVClass(java.lang.String, java.util.List, int)
	 */
	@Override
	public RVClass createRVClass(String name, List<UID> domain,
			int argumentCount) {
		
		return new RVClassImpl(name, domain, argumentCount);
	}

	/**
	 * {@inheritDoc}
	 * @see com.gr.experimental.model.MTheoryManager#createRVClassInfluence(com.gr.experimental.model.RVClass, int[])
	 */
	@Override
	public RVClassInfluence createRVClassInfluence(RVClass rvClass, int[] counts) {
		return new RVClassInfluenceImpl(rvClass, counts);
	}

	/**
	 * {@inheritDoc}
	 * @see com.gr.experimental.model.MTheoryManager#createOVariable(java.lang.String)
	 */
	@Override
	public OVariable createOVariable(String name) {
		return new OVariableImpl(name);
	}

	@Override
	public Distribution createConstDistribution(List<UID> domain,
			List<ObjectCount<RVClass>> parents, double[][] distrs,
			double[] defaultDistr) {
		return new ConstDistribution(domain, parents, distrs, defaultDistr);
	}

	@Override
	public Distribution createConstDistribution(List<UID> domain,
			double[] defaultDistr) {
		return new ConstDistribution(domain, defaultDistr);
	}

	@Override
	public Distribution createDistribution(String type, String description) {
            throw new IllegalStateException("Not yet implemented");
	}

	@Override
	public BuiltInElements getBuiltInElements() {
		return BuiltInElementsImpl.THIS_INSTANCE;
	}

	
	
}
